# coding=utf-8
import copy
import os
import re
import sys
import traceback

import openpyxl
import pandas
import pandas as pd
from loguru import logger
from openpyxl.reader.excel import load_workbook

from models.stock_model import StockNumber, DayInfo
from mylib import download_all
from mylib.mycsv import sort_csv2
from send_email import send_email_xlsx
from update_sh import get_sh_down_date


def get_3down_len(N, today_date, sn):
    """
    获取最近N次下跌，连续下跌天数计数
    """
    sc = f'stocks/{sn.ts_code}.csv'
    if not os.path.exists(sc):
        return None, None, None, None
    while not os.path.exists(sc):
        download_all.analysis_stock(sn)
    df = pandas.read_csv(sc)
    while str(df.iloc[0]['trade_date']) < str(today_date):
        download_all.analysis_stock(sn)
        df = pandas.read_csv(sc)
        if str(df.iloc[0]['trade_date']) >= str(today_date):
            logger.info(str(df.iloc[-1]['trade_date']).replace('-', ''))
            break
        else:
            logger.error(sn.name)
            return None, None, None, None
    today_d = None
    all_di = []
    all_di_high_low = []
    top_down = 0
    for row in df.index:
        d = DayInfo(sn, df.loc[row])
        if d.trade_date_str > today_date:
            continue
        if today_d is None:
            today_d = copy.deepcopy(d)
            if today_d.trade_date_str != today_date:
                return None, None, None, None
        all_di.append(d)
        all_di_high_low.append(d)
        if len(all_di) < N:
            continue
        all_di_high_n = [dd.high for dd in all_di_high_low]
        all_di_low_n = [dd.low for dd in all_di_high_low]
        if all_di_high_n[0] == max(all_di_high_n) or all_di_low_n[0] == min(all_di_low_n):
            if all_di_high_n[0] == max(all_di_high_n):
                top_down = 1
            else:
                top_down = 0
            break
        all_di_high_low.pop(0)
    res = re.findall('stocks/(.*).csv', sc)
    link_code_arr = res[0].split('.')
    link_code = f'{link_code_arr[1]}{link_code_arr[0]}'
    hyperlink = f'"https://xueqiu.com/S/{link_code}"'
    date_arr_hyp = f'=HYPERLINK({hyperlink})'
    logger.info(f'{today_date}, {sn.name}, {hyperlink}')
    dis2_top_low = (len(all_di) + 1 - N) if top_down else -(len(all_di) + 1 - N)
    return today_d, dis2_top_low, 0, date_arr_hyp


def get_all_stock_csv_path():
    for root, dirs, files in os.walk('stocks'):
        return [os.path.join(root, item) for item in files]


def run_down(stocks, cal_date, N, cal_len):
    today_date = str(cal_date[0])
    dname = os.path.basename(__file__).split('.')[0]
    log_dir = f'result_{dname}'
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)
    full_path_csv = f'{log_dir}/{today_date}_a_top_down_dis_rank_{N}.csv'
    f_tk = open(full_path_csv, 'w', encoding='utf-8')
    cal_date_str = ','.join(cal_date[::-1])
    f_tk.write(f'连接,{cal_date_str},dis2topd,dis2top,行业,name,代码,当前价格,日期')
    df = pd.read_csv('cal_ops/all.csv')
    full_path_txt = f'{log_dir}/{today_date}_top_down_dis_rank.txt'
    if os.path.exists(full_path_txt):
        os.remove(full_path_txt)
    logger.add(full_path_txt, format='{message}')
    cnt_number = 0
    for row in df.index:
        sn = StockNumber(df.loc[row])
        if 'ST' in sn.name:
            continue
        if '退' in sn.name:
            continue
        if not str(sn.ts_code).startswith('60') \
                and not str(sn.ts_code).startswith('30') \
                and not str(sn.ts_code).startswith('00'):
            continue
        if stocks and sn.name not in stocks:
            continue
        # if sn.industry not in [
        #     # '水力发电',
        #     # '小金属',
        #     '煤炭开采',
        #     # '黄金',
        #     # '铜',
        # ]:
        #     continue
        try:
            """
                elf.name = sn.name
                self.ts_code = sn.ts_code
                self.industry = sn.industry
                self.trade_date = df_row_data['trade_date']
                self.open = df_row_data['open']
                self.high = df_row_data['high']
                self.low = df_row_data['low']
                self.close = float(df_row_data['close'])
                self.pre_close = df_row_data['pre_close']
                self.change = df_row_data['change']
                self.pct_chg = float(df_row_data['pct_chg'])
                self.vol = df_row_data['vol']
                self.amount = df_row_data['amount']
            """
            msg_arr = None
            abs_pct_arr = []
            for d in cal_date:
                today_d, all_di_len, abs_pct, date_arr_hyp = get_3down_len(
                    N, d, sn)
                if today_d is None:
                    abs_pct_arr.append('0')
                    continue
                abs_pct_arr.append(str(all_di_len))
                if msg_arr is None:
                    msg_arr = [today_d, all_di_len, abs_pct, date_arr_hyp]
            if msg_arr:
                # 计算到最近一次 1 的距离
                start1 = 0
                start2 = 0
                idx = 0
                while 1:
                    idx += 1
                    if abs_pct_arr[idx] == '1' and not start1:
                        # 找到最近顶点
                        start1 = idx
                    if abs_pct_arr[idx] == '-1' and not start2:
                        # 找到最近低点
                        start2 = idx
                        break
                dis2top = start1
                top_down_dis = start2 - start1
                abs_pct_str = ','.join(abs_pct_arr[::-1])
                w_msg = f'\n{msg_arr[3]},{abs_pct_str},{top_down_dis},{dis2top},{sn.industry},{sn.name},{sn.ts_code},{msg_arr[0].close},{today_date}'
                logger.info(f'{today_date}, {sn.name}, {w_msg}')
                f_tk.write(w_msg)
                f_tk.flush()
                cnt_number += 1
        except Exception as e:
            print(e, traceback.format_exc())

    if os.path.exists(full_path_txt):
        os.remove(full_path_txt)

    f_tk.close()
    save_path_csv = full_path_csv.replace('.csv', f'_sort.csv')
    sort_csv2(save_path_csv, full_path_csv, ['dis2topd', 'dis2top'], [False, False])
    if os.path.exists(full_path_csv):
        os.remove(full_path_csv)
    result_xlsx = csv2excel(save_path_csv)
    if os.path.exists(save_path_csv):
        os.remove(save_path_csv)
    color_excel_file_path = red_min_value(result_xlsx, cal_len)
    if os.path.exists(result_xlsx):
        os.remove(result_xlsx)
    send_email_xlsx.send_xlsx(f'{cal_date[0]}_a_top_down_dis_rank', color_excel_file_path)


def red_min_value(excel_path, cal_len):
    wb = load_workbook(excel_path)
    sheet = wb['Sheet1']
    # 标记最小值的背景色为红色
    # 红色 FF0000
    # 绿色 00FF00
    # 白色 FFFFFF
    color_start_index = 2
    for row in sheet[2:sheet.max_row]:
        for cell in row:
            if color_start_index < cell.col_idx < (color_start_index + cal_len):
                # if float(cell.value) > float(1) or float(cell.value) == float(-1):
                if float(cell.value) == float(-1):
                    cell.fill = openpyxl.styles.PatternFill(start_color='00FF00', end_color='00FF00', fill_type='solid')
                elif float(cell.value) == float(1):
                    cell.fill = openpyxl.styles.PatternFill(start_color='FF0000', end_color='FF0000', fill_type='solid')
                else:
                    cell.fill = openpyxl.styles.PatternFill(start_color='FFFFFF', end_color='FFFFFF', fill_type='solid')
    # 保存工作簿
    color_excel_file_path = excel_path.replace('.xlsx', '_color.xlsx')  # 加载Excel文件
    if os.path.exists(color_excel_file_path):
        os.remove(color_excel_file_path)
    sheet.freeze_panes = "B2"
    wb.save(color_excel_file_path)
    return color_excel_file_path


def csv2excel(full_path_csv):
    # csv转excel
    try:
        excel_path = str(full_path_csv).replace('.csv', '.xlsx')
        # 读取CSV文件
        df = pd.read_csv(full_path_csv)
        # df_unique = df.drop_duplicates()
        # df2 = df_unique.iloc[:, :5]
        # 将DataFrame写入Excel文件
        # df2.to_csv(full_path_csv)
        df.to_excel(excel_path, index=False)
        return excel_path
    except Exception as e:
        print(e)


def get_stocks(txt_path):
    with open(txt_path) as fr:
        stocks_names = [item.strip() for item in fr.readlines() if item.strip()]
        return list(set(stocks_names))


if __name__ == '__main__':
    # 计算离最近左右N日，计算当前价与顶点下跌幅度
    cal_len = 50
    N = 5
    sh_dict, sh_date = get_sh_down_date()

    start_bkd = 0
    try:
        arguments = sys.argv[1:]
        if arguments:
            start_bkd = int(arguments[0])
        else:
            start_bkd = 0
    except Exception as e:
        start_bkd = 0
        logger.error(e)

    stocks = [
        # "中成股份",
        # "通威股份",
        # "中天科技",
        # "均胜电子",
        # "长江电力",
        # "隆基绿能",
        # "华电科工",
        # "明阳智能",
        # "众鑫股份",
    ]
    cal_date = sh_date[start_bkd:start_bkd + cal_len]
    run_down(stocks, cal_date, N, cal_len)
